package br.com.velp.sudecap.comum;

import br.com.velp.sudecap.entidade.DireitoSistema;
import br.com.velp.sudecap.enumerator.EnumChaveValor;
import br.com.velp.sudecap.enumerator.PermissaoEnum;
import br.com.velp.sudecap.enumerator.TipoMensagemEnum;
import br.com.velp.sudecap.mb.contexto.ContextoBean;
import br.com.velp.sudecap.util.JsfUtil;
import br.com.velp.sudecap.util.MensagemUtil;
import java.io.File;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.*;
import javax.faces.model.SelectItem;
import org.apache.commons.lang.StringUtils;
import org.primefaces.context.RequestContext;

/**
 * <sumario> <objetivo>"Rastreabilidade"</objetivo> <autor>EDUARDO SANTOS DE
 * OLIVEIRA</autor> <versao>1.0.0.0</versao> <data_criacao> 17.10.2012
 * </data_criacao> <data_ultima_alteracao> N/A </data_ultima_alteracao>
 * <descricao> Classe Base Para Operações Comuns Entre os Managead Beans
 * </descricao> </sumario>
 */
public class BaseController implements Serializable {

    private static final int REGISTROS_POR_PAGINA = 5;
    private static final String LINHAS_POR_PAGINA = "5, 10, 15, 20, 25, 30";
    private static final String RANGE_DATE_PICKER = "c-110:c+10";
    private String mensagem;
    private String tipoMensagem;
    private String tituloPainel;

    public BaseController() {
        
        this.mensagem = null;
        this.tipoMensagem = null;
        this.tituloPainel = null;
        
    }

    /*
     * Responsável Por Disponibilizar Uma Coleção de SelectItens Inicializada,
     * Incluindo a Opção "Selecione"
     *
     */
    protected List<SelectItem> obterSelectItemInicializado() {
	List<SelectItem> itens = new ArrayList<SelectItem>();
	itens.add(new SelectItem(null, MensagemUtil.getMensagem("opcao_combo_selecione")));
	return itens;
    }

    /*
     * Responsável Por Popular Uma Coleção de SelectItens, Recebendo Com
     * Argumento os Seguintes Parâmetros:
     *
     * - Collection (valores) - String atributoId - String atributoDescricao
     *
     * Obs.: Inclui a Opção "Selecione"
     *
     */
    protected List<SelectItem> obterSelectItemPopulado(Collection valores, String atributoId, String atributoDescricao) {

	return addItem(obterSelectItemInicializado(), valores, atributoId, atributoDescricao);

    }

    /*
     * Responsável Por Popular Uma Coleção de SelectItens, Recebendo Com
     * Argumento os Seguintes Parâmetros:
     *
     * - Collection (valores) - String atributoId - String atributoDescricao
     *
     * Obs.: Inclui a Opção "Selecione"
     *
     */
    protected List<SelectItem> obterSelectItemPopulado(boolean comSelecione, Collection valores, String atributoId, String atributoDescricao) {

        List<SelectItem> itens = new ArrayList<SelectItem>();;
        
        if (comSelecione) {
            itens = obterSelectItemInicializado();
        }

        return addItem(itens, valores, atributoId, atributoDescricao);

    }
    
    private List<SelectItem> addItem(List<SelectItem> itens, Collection valores, String atributoId, String atributoDescricao) {
        
	try {
            
	    for (Object value : valores) {

		Class clazz = value.getClass();

		Field fieldId = clazz.getDeclaredField(atributoId);
		Field fieldDescricao = clazz.getDeclaredField(atributoDescricao);

		if (fieldId != null && fieldDescricao != null) {

		    fieldId.setAccessible(true);
		    fieldDescricao.setAccessible(true);

		    Long valorId = (Long) fieldId.get(value);
		    String valorDescricao = (String) fieldDescricao.get(value);

		    itens.add(new SelectItem(valorId, valorDescricao));

		}

	    }

	    return itens;

	} catch (Exception e) {
            
	    return itens;
            
	}
        
    }
    
    /*
     * Responsável Por Popular Uma Coleção de SelectItens, Recebendo Com
     * Argumento os Seguintes Parâmetros:
     *
     * - Collection<EnumChaveValor> (valores)
     *
     */
    protected List<SelectItem> obterSelectItemPopulado(boolean comSelecione, EnumChaveValor... valores) {
	List<SelectItem> selectItens = new ArrayList<SelectItem>();
	if (comSelecione) {
	    selectItens = obterSelectItemInicializado();
	}
	for (EnumChaveValor item : valores) {
	    selectItens.add(new SelectItem(item.getValue(), item.getLabel()));
	}
	return selectItens;
    }

    /**
     * Verifica se o Usuário Possui Acesso ao Módulo ou a Funcionalidade
     *
     * @param Integer codigo (Código de Acesso ao Módulo)
     *
     * @return TRUE - Caso Possua Privilégio Sobre o Módulo / Funcionalidade
     * FALSE - Caso Contrário
     *
     */
    public boolean possuiPrivilegio(String nomeFuncionalidade) {
	Long codigo = obterCodigoAcesso(nomeFuncionalidade);
	ContextoBean contexto = (ContextoBean) JsfUtil.recuperarObjetoSessao("contextoBean");
	if (contexto == null || codigo == null) {
	    return false;
	}
	for (DireitoSistema direito : contexto.getPrivilegiosUsuario()) {
	    if (direito.getId().equals(codigo)) {
		return true;
	    }
	}
	return false;
    }

    protected boolean possuiPrivilegio(String... nomesFuncionalidades) {
	for (String func : nomesFuncionalidades) {
	    if (possuiPrivilegio(func)) {
		return true;
	    }
	}
	return false;
    }

    public void exibirPainelDialog(String nome) {
	RequestContext.getCurrentInstance().execute(nome.concat(".show();"));
    }

    public void ocultarPainelDialog(String nome) {
	RequestContext.getCurrentInstance().execute(nome.concat(".hide();"));
    }

    public void resetarFormulario(String form) {
	RequestContext.getCurrentInstance().reset(form);
    }

    /**
     * Recupera o Código de Acesso à Funcionalidade, de Acordo Com a Descrição
     * do Enumerator 'PermissaoEnum'
     *
     * @param String nomeFuncionalidade
     *
     * return Long codigoAcesso
     */
    private Long obterCodigoAcesso(String nomeFuncionalidade) {
	if (StringUtils.isNotBlank(nomeFuncionalidade)) {
	    PermissaoEnum permissao = PermissaoEnum.valueOf(nomeFuncionalidade);
	    return permissao != null ? permissao.getValue() : null;
	} else {
	    return null;
	}
    }

    /**
     * Responsavel Por Validar a Igualdade Entre Dois Objetos
     *
     * @param Object obj1
     * @param Object obj2
     * @return TRUE - Caso Sejam Iguais FALSE - Caso Contrário
     */
    protected boolean isIguais(Object obj1, Object obj2) {

	if (obj1 == null && obj2 == null) {
	    return true;
	}
	if (obj1 == null && obj2 != null) {
	    return false;
	}
	if (obj1 != null && obj2 == null) {
	    return false;
	}
	if (obj1 == "" && obj2 == "") {
	    return true;
	}

	return obj1.equals(obj2);

    }

    protected void tratarExcessao(Exception ex) {
	if (ex instanceof ValidationException) {
	    ValidationException ve = (ValidationException) ex;
	    for (String key : ve.getMensagens()) {
		MensagemUtil.exibirMensagemErro(MensagemUtil.getMensagem(key));
	    }
	} else {
	    MensagemUtil.exibirMensagemErro(ex.toString());
	}
    }
    
    public void exibirMensagem(TipoMensagemEnum tipoMsg, String mensagem){
        this.mensagem = "<ol><li>".concat(mensagem).concat("</li></ol>");
        this.tipoMensagem = tipoMsg.getTipoMensagem();
        this.tituloPainel = tipoMsg.getTituloPainel();
        exibirPainelDialog("painelMensagens");
    }
    
    public HashMap<String, Object> obterParametrosPadraoRelatorios(){
        
        HashMap<String, Object> parametros = new HashMap<String, Object>();
        
        parametros.put("LOGO_PBH", JsfUtil.getRealPath("/resources/imagens/logo_pbh.jpg"));
        parametros.put("LOGO_SUDECAP", JsfUtil.getRealPath("/resources/imagens/sudecap.jpg"));
        parametros.put("CABECALHO_DIR", JsfUtil.getRealPath("/relatorios").concat(File.separator));        
        parametros.put("REPORT_LOCALE", new Locale("pt", "BR"));
        
        return parametros;
        
    }
    
    // <editor-fold desc="GETTERS AND SETTERS" defaultstate="collapsed">    
    public ContextoBean getContexto() {
	return (ContextoBean) JsfUtil.recuperarObjetoSessao("contextoBean");
    }
    
    public String contextoAcesso() {
        return JsfUtil.getContexto();
    }
    
    public int getRegistrosPorPagina() {
	return REGISTROS_POR_PAGINA;
    }

    public String getLinhasPorPagina() {
	return LINHAS_POR_PAGINA;
    }

    public String getRangeDatePicker() {
	return RANGE_DATE_PICKER;
    }
    
    public String getMensagem() {
        return mensagem;
    }

    public void setMensagem(String mensagem) {
        this.mensagem = mensagem;
    }

    public String getTipoMensagem() {
        return tipoMensagem;
    }

    public void setTipoMensagem(String tipoMensagem) {
        this.tipoMensagem = tipoMensagem;
    }

    public String getTituloPainel() {
        return tituloPainel;
    }

    public void setTituloPainel(String tituloPainel) {
        this.tituloPainel = tituloPainel;
    }
    public boolean getExibirSubMenuTabelasBasicas(){
	return possuiPrivilegio(
                PermissaoEnum.LISTAR_USUARIO_LER.name(),
                PermissaoEnum.CADASTRAR_USUARIO_MANTER.name(),
                PermissaoEnum.GERENCIAR_GRUPO_USUARIO_LER.name(),
                PermissaoEnum.GERENCIAR_PERMISSAO_USUARIO_LER.name(),
                PermissaoEnum.LISTAR_CARTORIO_LER.name(),
                PermissaoEnum.CADASTRAR_CARTORIO_MANTER.name());
    }
    
    public boolean getExibirConteudoPaginaPrincipal(){
        return possuiPrivilegio(
                PermissaoEnum.PAGINA_INICIAL_ADMINISTRATIVO.name(),
                PermissaoEnum.PAGINA_INICIAL_AVALIACAO.name(),
                PermissaoEnum.PAGINA_INICIAL_DESAPROPRIACAO.name(),
                PermissaoEnum.PAGINA_INICIAL_JURIDICO.name(),
                PermissaoEnum.PAGINA_INICIAL_PLANEJAMENTO.name());
    }
    
    public boolean getExibirSubMenuRelatorioEmpreendimento(){
        return possuiPrivilegio(
                PermissaoEnum.RELATORIO_MONITORAMENTO_CONTROLE_EMPREENDIMENTO.name());
    }
    
    public boolean getExibirSubMenuRelatorioDesapropriacao(){
        return possuiPrivilegio(
                PermissaoEnum.RELATORIO_QUADRO_RESUMO_MULTIFAMILIAR.name());
    }
    
    public boolean getExibirMenuRelatorios(){
        return getExibirSubMenuRelatorioEmpreendimento() || getExibirSubMenuRelatorioDesapropriacao();
    } 
    
    public boolean getExibirMenuGestao() {
        return possuiPrivilegio(
                PermissaoEnum.CONSULTAR_LOGS_EVENTOS.name(),
                PermissaoEnum.CONFIGURACAO_SISTEMA.name(),
                PermissaoEnum.IMPORTACAO_XPLAN.name());
    }
    // </editor-fold>
    
}
